#include <iostream>
#include <thread>
#include <atomic>
using namespace std;
// int main()
// {
//     // int x = 0;
//     atomic<int> x(0);

//     thread t1([&x](){
//         for(size_t i = 0; i < 100000; ++i)
//              x.fetch_add(1, std::memory_order_relaxed);
//     });

//     thread t2([&x](){
//         for(size_t i = 0; i < 100000; ++i)
//             x.fetch_add(1, std::memory_order_relaxed);
//     });


//     t1.join();
//     t2.join();

//     cout << x << endl;

//     return 0;
// }

#include <iostream>
#include <atomic>

namespace gg
{
	template<class T>
	class shared_ptr
	{
	public:
		shared_ptr(T* ptr = nullptr)
			: _ptr(ptr)
			, _pcount(new std::atomic<int>(1))
		{}

		shared_ptr(const shared_ptr<T>& sp)
			: _ptr(sp._ptr)
			, _pcount(sp._pcount)
		{
			Add_count();
		}

		shared_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			if (this != &sp)
			{
				release();

				_ptr = sp._ptr;
				_pcount = sp._pcount;

				Add_count();
			}
			return *this;
		}

		int use_count() const
		{
			return _pcount ? _pcount->load() : 0; //load() 是 std::atomic<int> 提供的一个成员函数，用来获取原子类型变量的值。
		}

		void Add_count()
		{
			(*_pcount)++;
		}

		void release()
		{
			if (_pcount && _pcount->fetch_sub(1, std::memory_order_acq_rel) == 1)
			{
				std::cout << "~shared_ptr" << std::endl;
				delete _ptr;
				delete _pcount;
			}
			_ptr = nullptr;
			_pcount = nullptr;
		}

		~shared_ptr()
		{
			release();
		}

		T& operator*() { return *_ptr; }
		T* operator->() { return _ptr; }
	private:
		T* _ptr;
		std::atomic<int>* _pcount;
	};
}